#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: kong zhenzhen
@contact: gangkanli1219@gmail.com
@time: 2018/1/26 16:06
@desc:
"""
import base64
import collections
import json

import cv2
import numpy as np

from .basic import is_in_polygon


def image_encode_base64(image):
    """
    图像转换为base64编码,然后转换为字符串

    Parameters
    ----------
    image

    Returns
    -------

    """
    code = cv2.imencode('.jpg', image)[1]
    code = base64.b64encode(code)
    code = base64.encodebytes(code)
    code = bytes.decode(code)
    return code


def image_decode_base64(string):
    """
    将字符串转化为图像

    Parameters
    ----------
    string

    Returns
    -------

    """
    byte = str.encode(string)
    byte = base64.decodebytes(byte)
    byte = base64.b64decode(byte)
    byte = np.frombuffer(byte, np.uint8)
    img = cv2.imdecode(byte, cv2.CAP_MODE_RGB)
    return img


def get_rois_from_string(string):
    """
    字符串转化成roi 有序字典

    Parameters
    ----------
    string: 字典格式的字符串

    Returns
    -------

    """
    rois_string = eval(string)
    rois_string = sorted(rois_string.items(), key=lambda d: d[0], reverse=False)
    rois = collections.OrderedDict()
    for key, value in rois_string:
        rois[key] = list(map(lambda x: [x['y'], x['x']], value))
    return rois


def data_to_json_low(url, points, image=None, rois=None, store_id=0, types=None):
    """
    数据打包成json格式，为低密度检测

    Parameters
    ----------
    url: 图片链接
    points: 人的坐标
    image: 预测函数的返回值图像
    rois: roi区域
    store_id: 店id
    types: 标示展厅车展

    Returns
    -------

    """
    if rois is not None:
        img_roi = {}
        rois = get_rois_from_string(rois)
        for key, roi in rois.items():
            img_roi[key] = {}
            rois_point = []
            for point in points:
                if is_in_polygon(point, roi):
                    rois_point.append({'x': point[1], 'y': point[0]})
            img_roi[key]['is_high_density'] = 0
            img_roi[key]['people_num'] = len(rois_point)
            img_roi[key]['people_point'] = rois_point
        database = {"code": "200",
                    "data": {"image_roi": img_roi, "url": url, "store_id": store_id, "type": types}}
    else:
        rois_point = []
        for idx, point in enumerate(points):
            rois_point.append({'x': point[1], 'y': point[0]})
        database = {"code": "200",
                    "data": {"is_high_density": 0, "people_num": len(rois_point),
                             "people_point": rois_point, "url": url, "store_id": store_id,
                             "type": types}}

    database["pic_base64"] = image_encode_base64(image)
    in_json = json.dumps(database)
    return in_json


def data_to_json_high(url, density_map, rois=None,
                      store_id=0, types=None):
    """
    数据打包成json格式，为高密度检测

    Parameters
    ----------
    url: 图片链接
    density_map: 密度
    rois: roi区域
    store_id: 店id
    types: 标示展厅车展

    Returns
    -------

    """
    json_str = {'code': 200, 'data': {'store_id': store_id, 'type': types, 'url': url}}
    if rois is None:
        json_str['data']['is_high_density'] = 1
        json_str['data']['people_num'] = np.sum(density_map)
    else:
        rois_dict = get_rois_from_string(rois)
        json_str['data']['image_roi'] = {}
        for key, value in rois_dict.items():
            polygon = np.array(list(map(lambda x: [int(round(x[1] * density_map.shape[1])),
                                                   int(round(x[0] * density_map.shape[0]))], value)))
            mask = np.zeros(density_map.shape).astype(np.float32)
            cv2.fillConvexPoly(mask, polygon, 1.0)
            json_str['data']['image_roi'][key] = {'people_num': float(np.sum(mask * density_map)), 'is_high_density': 1}
    return json.dumps(json_str)
